package com.swak.frame.util;

import java.security.InvalidAlgorithmParameterException;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.StringUtils;
import org.slf4j.Logger;

import com.swak.frame.logger.SwakLoggerFactory;


/**
 * 
 * ClassName: AESUtil.java 
 * @Description: AES加密类
 * @author colley.ma
 * @date 2021年3月12日
 */
public class AESUtil {

	private static final IvParameterSpec DEFAULT_IV = new IvParameterSpec(new byte[]{0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0});

	private static final Logger logger = SwakLoggerFactory.getLogger(AESUtil.class);

	public static byte[] decrypt(byte[] content, String password) {
		try {
			KeyGenerator kgen = KeyGenerator.getInstance("AES");// 创建AES的Key生产者
			SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
			secureRandom.setSeed(password.getBytes(StringPool.UTF8));
			kgen.init(128,secureRandom);
			SecretKey secretKey = kgen.generateKey();// 根据用户密码，生成一个密钥
			byte[] enCodeFormat = secretKey.getEncoded();// 返回基本编码格式的密钥
			SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 转换为AES专用密钥
			Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");// 创建密码器
			try {
				cipher.init(Cipher.DECRYPT_MODE, key,DEFAULT_IV);// 初始化为解密模式的密码器
			} catch (InvalidAlgorithmParameterException e) {
				logger.error(e.getMessage(),e);
			}
			byte[] result = cipher.doFinal(content);
			return result; // 明文

		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		} 
		return null;
	}

	public static byte[] encrypt(String content, String password){
		try {
			KeyGenerator kgen = KeyGenerator.getInstance("AES");// 创建AES的Key生产者

			// new SecureRandom(password.getBytes()) LINUX下将导致同一seed不同结果
			// LINUX采用NativePRNG算法(随机数取自/dev/random和/dev/urandom 与入参seed没关系) Windows采用SHA1PRNG算法  测试见方法testSecureRandom

			SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
			secureRandom.setSeed(password.getBytes(StringPool.UTF8));
			kgen.init(128, secureRandom);// 利用用户密码作为随机数初始化出 128位的key生产者

			SecretKey secretKey = kgen.generateKey();// 根据用户密码，生成一个密钥

			byte[] enCodeFormat = secretKey.getEncoded();// 返回基本编码格式的密钥，如果此密钥不支持编码，则返回
															// null。
			SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 转换为AES专用密钥
			Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");// 创建密码器

			byte[] byteContent = (content.getBytes());

			try {
				cipher.init(Cipher.ENCRYPT_MODE, key,DEFAULT_IV);
			} catch (InvalidAlgorithmParameterException e) {
				logger.error(e.getMessage(),e);
			}

			byte[] result = cipher.doFinal(byteContent);// 加密

			return result;

		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		} 
		return null;
	}

	public static String encryptByDefault(String content) {
		byte[] encodeResult = encrypt(content, StringPool.KEY);
		String encodeStr = Base64Util.encode2Str(encodeResult, StringPool.UTF8, true);
		//去掉换行符 base64超过76字符自动加换行符
		encodeStr = encodeStr.replaceAll("\r\n", "");
		return encodeStr;
	}


	public static String decryptByDefault(String content) {
		byte[] byteArray = Base64Util.decode(content.getBytes(), true);
		byte[] decryptResult = decrypt(byteArray, StringPool.KEY);
		return StringUtils.newStringUtf8(decryptResult);
	}
	
	
	public static void main(String[] args) {
		System.out.println("AES-CFB:"+encryptByDefault("copy1@"));
		System.out.println("Blowfish:"+BlowfishCipherHelper.encrypt("copy1@"));
		System.out.println(encryptByDefault(System.currentTimeMillis()+"@copy1"));
		System.out.println(decryptByDefault("GJHITatQNGVGw3tPNr4aU5Njtw"));
		String st = "1610504827117@copy1";
		System.out.println(org.apache.commons.lang3.StringUtils.substring("1610504827117@copy1", st.indexOf("@")+1));
	}


}
